package com.ld.task;

import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 条件阻塞Condition
 */
public class UseCondition {

    static Lock lock = new ReentrantLock(); // 可重入锁
    static Condition packCondition = lock.newCondition(); //包装
    static Condition workCondition = lock.newCondition(); //生产
    static Condition repairCondition = lock.newCondition(); //维修
    static Boolean finish = false;
    //包装类
    static class Pack implements Runnable {
        @Override
        public void run() {
            lock.lock();
            try {
                int i = 1;
                do {
                    System.out.println("包装部门等待包装");
                    packCondition.await();
                    Thread.sleep(2000);
                    System.out.println("包装部门包装好第" + i + "包");
                    workCondition.signal();
                    i++;
                } while (i <= 5);
                finish = true;
                repairCondition.signal();
                System.out.println("包装部门工作完成");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        }
    }
    //生产部门
    static class Work implements Runnable {
        @Override
        public void run() {
            lock.lock();
            try {
                int i=0;
                do {
                    System.out.println("生产部门开始生产");
                    Thread.sleep(2000);
                    Random random = new Random();
                    int num = random.nextInt(10);
                    System.out.println("随机数是"+num);
                    if (num % 4 != 0) {
                        //生产部门完成工作，通知包装部门
                        System.out.println("生产部门生产完成，通知包装部门包装,等待包装部回馈");
                        packCondition.signal();
                        workCondition.await();
                        System.out.println("生产部门收到包装部门完成回馈，检查是否完成");
                        i++;
                    } else {
                        //生产部门通知维修部门修机器
                        System.out.println("机器坏了，生产部门通知维修部门修机器,并等待修好");
                        repairCondition.signal();
                        workCondition.await();
                        System.out.println("机器修好，开始工作。");
                    }
                } while (!finish);
                System.out.println("生产部门完成了今天的工作，共生产了"+i+"包");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }

    //维修部门
    static class Repair implements Runnable {
        @Override
        public void run() {
            lock.lock();
            try {
                do {
                    System.out.println("维修部门待命");
                    repairCondition.await();
                    if(finish){
                        System.out.println("工作完成,维修部门结束工作");
                        break;
                    }
                    System.out.println("维修部门接到通知开始修机器");
                    Thread.sleep(2000);
                    System.out.println("维修部门修好机器通知生产部");
                    workCondition.signal();
                } while (true);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new Thread(new Pack()).start();
        new Thread(new Repair()).start();
        new Thread(new Work()).start();
    }
}
